package jastgen.generator;

import static jastgen.generator.Generator.toVisitReturnType;
import jastgen.nodes.ClassDef;
import jastgen.nodes.Field;

import java.io.PrintWriter;

class Helper {

	// 3箇所 (in, in, exit)
	static void printVisitC(
			final PrintWriter out,
			final ClassDef n,
			final String prefix)
	{
		printVisitC(out, n, prefix, "void", true);
	}

	// 3箇所
	static void printVisitC(
			final PrintWriter out,
			final ClassDef n,
			final String prefix,
			final String retTy,
			final boolean isOverride)
	{
		final String ps = n.getTypeParamsString();
		final String bn = n.getBaseName();
		final String cn = n.getName();
		if(isOverride)
			out.println("	@Override");
		out.println("	public " + ps + retTy + " " + prefix + bn + "(");
		out.println("			final " + cn + " node)");
	}

	// 2箇所 (両方とも@Overrideは無し)
	static void printVisitI(
			final PrintWriter out,
			final ClassDef n,
			final String retTy)
	{
		final String ps = n.getTypeParamsString();
		final String bn = n.getBaseName();
		final String cn = n.getName();
		out.println("	" + ps + retTy + " in" + bn + "(" + cn + " node);");
	}

	// 3箇所
	static void printMethod(
			final PrintWriter out,
			final ClassDef n,
			final String retTy)
	{
		final String ps = n.getTypeParamsString();
		final String bn = n.getBaseName();
		final String cn = n.getName();
		out.println();
		out.println("	@Override");
		out.println("	public " + ps + retTy + " in" + bn + "(final " + cn + " node) {");
		out.println("		throw new UnsupportedOperationException(");
		out.println("			\"Not implemented yet!\");");
		out.println("	}");
	}

	// 2箇所
	static String retTy(final ClassDef n) {
		return toVisitReturnType(n.getInterfaceOrClassBaseName());
	}

	// 2箇所
	static void printNullableVisit(
			final PrintWriter out)
	{
		out.println("	{");
		out.println("		if(n == null)");
		out.println("			return null;");
		out.println("		return n.visit(this);");
		out.println("	}");
	}

	// 2箇所
	static void printContextFactoryParams(
			final PrintWriter out,
			final ClassDef node)
	{
		boolean is1st = true;
		for(final Field f : node.getFields()) {
			if(f.hasBody())
				continue;
			if(!is1st) out.print(",");
			is1st = false;
			out.println();
			out.print("			final " + f.getType() + " " + f.getName());
		}
	}

	// 2箇所
	static void printContextFactoryArgs(
			final PrintWriter out,
			final ClassDef node,
			boolean is1st)
	{
		for(final Field f : node.getFields()) {
			if(f.hasBody())
				continue;
			if(!is1st) out.print(",");
			is1st = false;
			out.println();
			out.print("				" + f.getName());
		}
	}
}
